require 'active_record'

module ActiveRecord
  module HasGeneratedCode
    extend ActiveSupport::Concern
    module ClassMethods

      def has_generated_code(attribute = :code, **options)
        attribute, length = { attribute: attribute, length: 8 }.merge(options).values
        define_method("generate_#{attribute}") do |arg|
          generated = nil
          loop do
            generated = HasGeneratedCode.generate_random_code(arg)
            break unless self.class.where("#{attribute}=?", generated).any?
          end
          self.send("#{attribute}=", generated)
        end
        before_create { self.send("generate_#{attribute}", length) unless self.send("#{attribute}?") }
      end
    end
    def self.generate_random_code(length)
      charset = %w(2 3 4 6 7 9 A C D E F G H J K M N P Q R T V W X Y Z)
      (0...length).map { charset.to_a[rand(charset.size)] }.join
    end
  end
end

ActiveRecord::Base.send(:include, ActiveRecord::HasGeneratedCode)
